package cn.edu.pku.ss.situationawareperceiver;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;


import android.app.Activity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
	private static final String TAG = "MainActivity";
	/* Load the native alljoyn_java library. */
	static {
		System.loadLibrary("alljoyn_java");
	}

	/* Handler used to make calls to AllJoyn methods. See onCreate(). */
	private BusHandler mBusHandler;
	private UIHandler mUIHandler;
	private SituationReasoner mSituationReasoner;

	/* UI members */
	private Button mSendBtn;
	TextView connectStatus_TextView; // TextView for Connect Status
	TextView groupStatus_TextView; // TextView for group status
	TextView peerslist_TextView; // TextView for peers in the group

	/* Database adapter */
	private DBAdapter dbAdapter;
	
	RelativeLayout cloudTag_Layout;// View to show 3d cloud tags
	TagCloudView mTagCloudView; // the 3d cloud view

	private List<Tag> mTagList;

	private HashMap<Integer, Situation> situations;
	private HashMap<Integer, Tag> tags;
	
	private boolean isTimerOn = false;
	
	//unified date format
	public DateFormat mDateFormat;
	
	
	//private SingleChoiceDialog mSingleChoiceDialog;  //Dialog to choose sensorConfiguration
	//private List<String> mSingleDataList;
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mUIHandler = new UIHandler(this);

		/*
		 * Make all AllJoyn calls through a separate handler thread to prevent
		 * blocking the UI.
		 */
		HandlerThread busThread = new HandlerThread("BusHandler");
		busThread.start();
		mBusHandler = new BusHandler(busThread.getLooper(), mUIHandler, this);

		// assign the bus handler to ContextShareManager
		ContextShareManager.getInstance().setBusHandler(mBusHandler);
		ContextShareManager.getInstance().setMainActivity(this);

		/* Find UI members */
		mSendBtn = (Button) findViewById(R.id.sendRequestBtn);
		connectStatus_TextView = (TextView) findViewById(R.id.connectStatusTextView);
		groupStatus_TextView = (TextView) findViewById(R.id.groupStatusTextView);
		peerslist_TextView = (TextView) findViewById(R.id.peersTextView);
		cloudTag_Layout = (RelativeLayout) findViewById(R.id.cloudTagLayout);

		/* unified date format*/
		mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		/* create dbadapter object*/
		dbAdapter = new DBAdapter(getApplicationContext());
		
		/* Start the SRA */
		mSituationReasoner = new SituationReasoner(mUIHandler, this);
		

		/* Random set a sensor configuration */
//		Random randSensorCon = new Random();
//		int sensorConId = randSensorCon.nextInt(4);
//		SensorManager.getInstance().readSensors(sensorConId);
//		logInfo("Sensor Configuration: " + sensorConId);

		// Step1: get screen resolution:
		tags = new HashMap<Integer, Tag>();

		Display display = getWindowManager().getDefaultDisplay();
		int width = display.getWidth();
		int height = display.getHeight() + connectStatus_TextView.getHeight()
				+ groupStatus_TextView.getHeight()
				+ peerslist_TextView.getHeight();

		// Step2: create the required TagList:
		// notice: All tags must have unique text field
		// if not, only the first occurrence will be added and the rest will be
		// ignored
		List<Tag> myTagList = createTags();

		// Step3: create our TagCloudview and set it as the content of our
		// MainActivity
		mTagCloudView = new TagCloudView(this, width, height, myTagList); // passing
																			// current
																			// context
		// setContentView(mTagCloudView);
		cloudTag_Layout.addView(mTagCloudView);
		mTagCloudView.requestFocus();
		mTagCloudView.setFocusableInTouchMode(true);

		mSendBtn.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View arg0) {
				if(!isTimerOn){
					isTimerOn = true;	//turn on the timer
					clearAndGenerateContextShareRequest();	//first call
					String strMsg = "Timer has turned on.";
					Message tMsg = mUIHandler.obtainMessage(UIHandler.TOAST_MSG, strMsg);
					mUIHandler.sendMessage(tMsg);
					logInfo(strMsg);
				}else{
					isTimerOn = false;	//turn off the timer
					String strMsg = "Timer has turned off.";
					Message tMsg = mUIHandler.obtainMessage(UIHandler.TOAST_MSG, strMsg);
					mUIHandler.sendMessage(tMsg);
					logInfo(strMsg);
				}
			}
		});
		
		 /*mSingleDataList = new ArrayList<String>();
	        
         mSingleDataList.add("sensors:0");    
         mSingleDataList.add("sensors:1");  
         mSingleDataList.add("sensors:2");
         mSingleDataList.add("sensors:3");  
	     mSingleChoiceDialog = new SingleChoiceDialog(this, mSingleDataList);
         mSingleChoiceDialog.setTitle("Please choose sensor config.");
         mSingleChoiceDialog.setOnOKButtonListener(new DialogInterface.OnClickListener() {

                     public void onClick(DialogInterface dialog, int which) {
                             // TODO Auto-generated method stub
                             int selItem = mSingleChoiceDialog.getSelectItem();    
                             
                             Get the choice
                             SensorManager.getInstance().readSensors(selItem);
                             
                             Start SRA
                             mSituationReasoner.startSRA(getApplicationContext());
                             
                              Bus Handler takes over and initialize the network environment. 
                     		mBusHandler.sendEmptyMessage(BusHandler.INIT);

                     		mBusHandler.postDelayed(new Runnable() {
                     			@Override
                     			public void run() {
                     				mBusHandler.sendEmptyMessage(BusHandler.JOINORCREATE);
                     			}
                     		}, 2000);
                     }
                      
              
             });
		
        mSingleChoiceDialog.show();
         */
		int selItem = (int)(Math.random()*3);   
        
        //Get the choice
        SensorManager.getInstance().readSensors(selItem);
        
        //Start SRA
        mSituationReasoner.startSRA(getApplicationContext());
        
         //Bus Handler takes over and initialize the network environment. 
		mBusHandler.sendEmptyMessage(BusHandler.INIT);

		mBusHandler.postDelayed(new Runnable() {
			@Override
			public void run() {
				mBusHandler.sendEmptyMessage(BusHandler.JOINORCREATE);
			}
		}, 2000);
	}

	private List<Tag> createTags() {
		// create the list of tags with popularity values and related url
		mTagList = new ArrayList<Tag>();

		situations = mSituationReasoner.getAllSituation();

		Iterator iter = situations.entrySet().iterator();

		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			Tag tempTag = new Tag(((Situation) entry.getValue()).getName(),
					(Integer) entry.getKey(), "haha", false);
			if (!((Situation) entry.getValue()).isTransparent())
				mTagList.add(tempTag);
			tags.put((Integer) entry.getKey(), tempTag);
		}

		return mTagList;
	}

	public void activateTag(int tagId) {
		if (!tags.containsKey(tagId)) // transparent
			return;
		Tag tempTag = tags.get(tagId);
		tempTag.setActive(true);
		mTagCloudView.Replace(tempTag, tempTag.getText());
		// mTagCloudView.reset();
	}

	public void unactivateTag(int tagId) {
		if (!tags.containsKey(tagId)) // transparent
			return;
		Tag tempTag = tags.get(tagId);
		if (tempTag.isActive()) {
			tempTag.setActive(false);
			mTagCloudView.Replace(tempTag, tempTag.getText());
		}
	}

	public void showProcess(List<Integer> ids) {
		if (ids.size() < 2)
			return;
		logInfo("show abductive process (abductive node id " + ids.get(0)
				+ ").");
		LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
		View view = inflater.inflate(R.layout.show_process,
				(ViewGroup) findViewById(R.id.toast_layout_root));
		TextView abductiveNodeView = (TextView) view
				.findViewById(R.id.abductiveNode);
		TextView explanationNodesView = (TextView) view
				.findViewById(R.id.explanationNodes);
		// abductiveNodeView.setText(tags.get(ids.get(0)).getText());
		abductiveNodeView.setText(situations.get(ids.get(0)).getName());
		String tempString = "";
		for (int i = 1; i < ids.size(); i++) {
			// tempString+=tags.get(ids.get(i)).getText()+"\n";
			tempString += situations.get(ids.get(i)).getName() + "\n";
		}
		explanationNodesView.setText(tempString);
		Toast toast = new Toast(MainActivity.this);
		toast.setDuration(Toast.LENGTH_LONG);
		toast.setView(view);
		toast.setGravity(Gravity.CENTER, 0, 0);
		toast.show();

		activateTag(ids.get(0));
	}

	@Override
	protected void onDestroy() {
		//reset
	
		/* Unactivate all tags */
		for(int itag:tags.keySet()){
			unactivateTag(itag);
		}
		
		/* Clear all local contexts */
		ContextShareManager.getInstance().clearLocalContexts();
		
		// Inform bus handler to cleanup
		mBusHandler.sendEmptyMessage(BusHandler.CLEANUP);
		if(null != dbAdapter){
			dbAdapter.close();
		}
		super.onDestroy();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public DBAdapter getDBAdapter(){
		if(null !=dbAdapter)
			return dbAdapter;
		else{
			Log.e(TAG, "getDBAdapter(): return NULL.");
			return null;
		}
	}
	
	public void clearAndGenerateContextShareRequest(){
		/* send ui toast */
		
		/* 1. Clean SRA and end its running */		
		mSituationReasoner.resetSRA();
		
		/* 2. Unactivate all tags */
		for(int itag:tags.keySet()){
			unactivateTag(itag);
		}
		
		/* 3. Clear all local contexts */
		ContextShareManager.getInstance().clearLocalContexts();
		
		/* 4. Send a random context share request over the proximity */
		// get time
		java.util.Date dt = new Date();
		long lSysTime1 = dt.getTime() / 1000; 

		// Mock
		Random rand = new Random();
		int randInt = rand.nextInt(20);
		ContextShareRequest request = new ContextShareRequest();
		request.initialize(mBusHandler.getMyPeerId(), randInt, lSysTime1,
				1000);
		Message msg = mBusHandler.obtainMessage(
				BusHandler.SEND_SHARE_REQUEST, request);
		mBusHandler.sendMessage(msg);
		
		mUIHandler.sendEmptyMessageDelayed(UIHandler.CLEAR_AND_REGENERATE_REQUEST, 30000);
		
	}
	
	public boolean isTimerOn() {
		return isTimerOn;
	}
	
	public DateFormat getUnifiedDateFormat(){
		return mDateFormat;
	}

	/* Log methods */
	public static void logInfo(String msg) {
		Log.i(TAG, msg);
	}
}
